'use client';

import {
  type ChangeEvent,
  type FormEvent,
  useEffect,
  useRef,
  useState,
} from 'react';
import { useMutation } from '@tanstack/react-query';
import diff from 'microdiff';
import type { IDifference, IPostBadge, IQueryPostDetails } from '@/interfaces';
import type { TBadgeBackgroundColorMode, TBadgeColorMode } from '@/types';
import useToast from '@/hooks/useToast';
import { getDiffData } from '@/lib/tool';
import IroItem from '@/app/[locale]/admin/forum/post/update/IroItem';
import {
  createPostBadge,
  removePostBadge,
  updatePostBadge,
} from '@/services/api';
import classNames from 'classnames';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import Box from '@/app/[locale]/admin/common/box';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

const defaultForm: any = {
  name: '',
  sort: 0,
  reason: '',
  colorMode: 'DEFAULT',
  color: '#ffffff',
  backgroundColorMode: 'DEFAULT',
  backgroundColor: '#0dcaf0',
  roundedPill: false,
};

export default function UpdatePostBadge(
  this: any,
  {
    source,
    translatedFields,
  }: {
    source: IQueryPostDetails;
    translatedFields: PrefixedTTranslatedFields<'postAdminPage'>;
  },
) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    name?: string;
    sort?: number;
    reason?: string;
    colorMode?: TBadgeColorMode;
    color?: string;
    backgroundColorMode?: TBadgeBackgroundColorMode;
    backgroundColor?: string;
    roundedPill?: boolean;
  }>(defaultForm);
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [currentItem, setCurrentItem] = useState<IPostBadge>();
  const [currentRemoveItem, setCurrentRemoveItem] = useState<IPostBadge>();
  const selectColorModeRef = useRef<HTMLSelectElement>(null);
  const selectBackgroundColorModeRef = useRef<HTMLSelectElement>(null);
  const [selectColorMode, setSelectColorMode] = useState('HEX');
  const [selectBackgroundColorMode, setSelectBackgroundColorMode] =
    useState('HEX');
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const createPostBadgeMutation = useMutation(createPostBadge);
  const updatePostBadgeMutation = useMutation(updatePostBadge);
  const removePostBadgeMutation = useMutation(removePostBadge);

  useEffect(() => {
    let _form: any;
    if (currentItem) {
      _form = {
        name: currentItem.name,
        sort: currentItem.sort,
        reason: currentItem.reason,
        colorMode: currentItem.colorMode,
        color: currentItem.color,
        backgroundColorMode: currentItem.backgroundColorMode,
        backgroundColor: currentItem.backgroundColor,
        roundedPill: currentItem.roundedPill,
      };
    } else {
      _form = defaultForm;
    }

    const diffData = diff(_form, form);
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, currentItem]);

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();

      const data = getDiffData(differenceData);

      if (currentItem) {
        if (
          data.name &&
          source.basic.badges.find((item) => item.name === data.name)
        ) {
          delete data.name;
        }

        await updatePostBadgeMutation.mutateAsync({
          id: currentItem,
          data: data,
        });
      } else {
        await createPostBadgeMutation.mutateAsync({
          data: {
            name: data.name,
            postId: source.basic.id,
          },
        });

        setForm(defaultForm);
      }

      show({
        type: 'SUCCESS',
        message: translatedFields.saveCompleted,
      });
    } catch (e) {
      if (currentItem) {
        updatePostBadgeMutation.reset();
      } else {
        createPostBadgeMutation.reset();
      }

      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
      setCurrentItem(undefined);
    }
  }

  function onClickItem(item: IPostBadge) {
    setCurrentItem(item);
    setForm({
      ...form,
      ...{
        name: item.name,
        sort: item.sort,
        reason: item.reason,
        colorMode: item.colorMode,
        color: item.color,
        backgroundColorMode: item.backgroundColorMode,
        backgroundColor: item.backgroundColor,
        roundedPill: item.roundedPill,
      },
    });
  }

  function onClickCancel() {
    setCurrentItem(undefined);
    setForm({ ...form, ...defaultForm });
  }

  async function onClickRemove(item: IPostBadge) {
    try {
      setCurrentRemoveItem(item);

      await removePostBadgeMutation.mutateAsync({
        id: item.id,
      });

      setCurrentItem(undefined);
      show({
        type: 'SUCCESS',
        message: translatedFields.deleteCompleted,
      });
    } catch (e) {
      removePostBadgeMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
      setCurrentItem(undefined);
      setCurrentRemoveItem(undefined);
    }
  }

  function checkForm() {
    const name = form.name;

    if (!name) {
      throw translatedFields.nameRequired;
    }

    if (
      !currentItem &&
      source.basic.badges.find((item) => item.name === name)
    ) {
      throw translatedFields.nameDuplicated;
    }
  }

  function onChangeForm(e: ChangeEvent<HTMLSelectElement | HTMLInputElement>) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'roundedPill') {
      setForm({ ...form, roundedPill: value === 'true' });
    } else if (name === 'sort') {
      setForm({ ...form, sort: parseInt(value) });
    } else if (name === 'selectColorMode') {
      setSelectColorMode(value);
    } else if (name === 'selectBackgroundColorMode') {
      setSelectBackgroundColorMode(value);
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  function changeColorCallback(color: string) {
    if (!color) {
      return;
    }

    setForm({ ...form, color });
  }

  function changeBackgroundColorCallback(color: string) {
    if (!color) {
      return;
    }

    setForm({ ...form, backgroundColor: color });
  }

  return (
    <Box>
      <div className="vstack gap-4">
        {source.basic.badges.length > 0 && (
          <div className="table-responsive">
            <table className="table align-middle">
              <thead>
                <tr className="text-nowrap">
                  <th scope="col" className="fw-normal">
                    {translatedFields.badgePage.name}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.badgePage.sort}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.badgePage.reason}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.badgePage.color}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.badgePage.backgroundColor}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.badgePage.ovalStyle}
                  </th>
                  <th scope="col" className=""></th>
                </tr>
              </thead>
              <tbody>
                {source.basic.badges.map((item) => {
                  return (
                    <tr
                      key={item.id}
                      className={classNames('text-nowrap', {
                        'table-active':
                          currentItem && currentItem.id === item.id,
                      })}
                    >
                      <td
                        className="cursor-pointer"
                        onClick={onClickItem.bind(this, item)}
                      >
                        <span
                          className={classNames('badge', {
                            'rounded-pill': item.roundedPill,
                          })}
                          style={{
                            color:
                              item.colorMode === 'DEFAULT'
                                ? '#ffffff'
                                : item.color,
                            backgroundColor:
                              item.backgroundColorMode === 'DEFAULT'
                                ? '#0dcaf0'
                                : item.backgroundColor,
                          }}
                        >
                          {item.name}
                        </span>
                      </td>
                      <td
                        className="cursor-pointer"
                        onClick={onClickItem.bind(this, item)}
                      >
                        {item.sort}
                      </td>
                      <td
                        className="cursor-pointer"
                        onClick={onClickItem.bind(this, item)}
                      >
                        {item.reason}
                      </td>
                      <td
                        className="cursor-pointer"
                        onClick={onClickItem.bind(this, item)}
                      >
                        {`${
                          translatedFields.badgePage.BADGE_COLOR_MODE[
                            item.colorMode
                          ]
                        } (${item.color})`}
                      </td>
                      <td
                        className="cursor-pointer"
                        onClick={onClickItem.bind(this, item)}
                      >
                        {`${
                          translatedFields.badgePage.BADGE_COLOR_MODE[
                            item.backgroundColorMode
                          ]
                        } (${item.backgroundColor})`}
                      </td>
                      <td
                        className="cursor-pointer"
                        onClick={onClickItem.bind(this, item)}
                      >
                        {item.roundedPill
                          ? translatedFields.yes
                          : translatedFields.no}
                      </td>
                      <td>
                        {currentItem && currentItem.id === item.id && (
                          <button
                            onClick={onClickCancel}
                            className="btn btn-sm btn-light me-2"
                            type="button"
                          >
                            {translatedFields.cancel}
                          </button>
                        )}

                        <button
                          disabled={
                            currentRemoveItem &&
                            currentRemoveItem.id === item.id &&
                            removePostBadgeMutation.isLoading
                          }
                          onClick={onClickRemove.bind(this, item)}
                          className="btn btn-sm btn-danger"
                          type="button"
                        >
                          {currentRemoveItem &&
                          currentRemoveItem.id === item.id &&
                          removePostBadgeMutation.isLoading ? (
                            <span
                              className="spinner-border spinner-border-sm me-2"
                              role="status"
                              aria-hidden="true"
                            ></span>
                          ) : (
                            <i className="bi bi-trash me-2"></i>
                          )}
                          {translatedFields.delete}
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}

        {form.name && (
          <div className="card position-relative">
            <div className="card-body text-center">
              <div
                className="position-absolute text-secondary"
                style={{
                  left: '-1rem',
                  top: '-0.7rem',
                  transform: 'skew(15deg)',
                }}
              >
                {translatedFields.preview}
              </div>
              <span
                className={classNames('badge me-2', {
                  'rounded-pill': form.roundedPill,
                })}
                style={{
                  color: form.colorMode === 'DEFAULT' ? '#ffffff' : form.color,
                  backgroundColor:
                    form.backgroundColorMode === 'DEFAULT'
                      ? '#0dcaf0'
                      : form.backgroundColor,
                }}
              >
                {form.name}
              </span>
              <span>{source.basic.name}</span>
            </div>
          </div>
        )}

        <form onSubmit={onClickSave} className="vstack gap-4">
          <div>
            <label className="form-label">
              {translatedFields.badgePage.name}
            </label>
            <input
              type="text"
              className="form-control"
              name="name"
              value={form.name}
              onChange={onChangeForm}
              aria-describedby="name"
              placeholder={translatedFields.badgePage.namePlaceholder}
            />
          </div>

          {currentItem && (
            <>
              <div>
                <label className="form-label">
                  {translatedFields.badgePage.sort}
                </label>
                <input
                  min={0}
                  type="number"
                  className="form-control"
                  name="sort"
                  value={form.sort}
                  onChange={onChangeForm}
                  aria-describedby="sort"
                  placeholder={translatedFields.badgePage.sortPlaceholder}
                />
              </div>

              <div>
                <label className="form-label">
                  {translatedFields.badgePage.reason}
                </label>
                <input
                  type="text"
                  className="form-control"
                  name="reason"
                  value={form.reason}
                  onChange={onChangeForm}
                  aria-describedby="reason"
                  placeholder={translatedFields.badgePage.reasonPlaceholder}
                />
              </div>

              <div>
                <label className="form-label">
                  {translatedFields.badgePage.colorMode}
                </label>
                <div className="form-control user-select-none">
                  {['DEFAULT', 'CUSTOM'].map((item) => {
                    return (
                      <div key={item} className="form-check form-check-inline">
                        <input
                          id={`yw-badge-colorMode-${item}`}
                          name="colorMode"
                          className="form-check-input"
                          type="radio"
                          onChange={onChangeForm}
                          value={item}
                          checked={form.colorMode === item}
                        />
                        <label
                          className="form-check-label"
                          htmlFor={`yw-badge-colorMode-${item}`}
                        >
                          {
                            (translatedFields as any).badgePage
                              .BADGE_COLOR_MODE[item]
                          }
                        </label>
                      </div>
                    );
                  })}
                </div>
              </div>

              {form.colorMode === 'CUSTOM' && (
                <div>
                  <label className="form-label">
                    {translatedFields.badgePage.color}
                  </label>
                  <div className="row align-items-center gap-4">
                    <div className="col-4">
                      <div className="vstack gap-4">
                        <div className="row gap-4 align-items-center">
                          <div className="col-2"></div>
                          <div className="col">
                            <select
                              ref={selectColorModeRef}
                              name="selectColorMode"
                              value={selectColorMode}
                              onChange={onChangeForm}
                              className="form-select"
                              aria-label="selectColorMode"
                              placeholder={
                                translatedFields.badgePage
                                  .colorOutputTypePlaceholder
                              }
                            >
                              <option value="HEX">HEX</option>
                              <option value="RGB">RGB</option>
                              <option value="RGBA">RGBA</option>
                              <option value="HSL">HSL</option>
                              <option value="HSLA">HSLA</option>
                            </select>
                          </div>
                        </div>

                        <input
                          type="text"
                          className="form-control"
                          name="color"
                          value={form.color}
                          onChange={onChangeForm}
                          aria-describedby="color"
                          placeholder={
                            translatedFields.badgePage.colorPlaceholder
                          }
                        />

                        <div className="form-text">
                          {translatedFields.badgePage.sliderBarPlaceholder}
                        </div>
                      </div>
                    </div>
                    <div className="col-7">
                      <IroItem
                        inputColor={form.color}
                        selectColorModeRef={selectColorModeRef}
                        changeColorCallback={changeColorCallback}
                      />
                    </div>
                  </div>
                </div>
              )}

              {form.name &&
                (form.colorMode === 'CUSTOM' ||
                  form.backgroundColorMode === 'CUSTOM') && (
                  <div className="card position-relative">
                    <div className="card-body text-center">
                      <div
                        className="position-absolute text-secondary"
                        style={{
                          left: '-1rem',
                          top: '-0.7rem',
                          transform: 'skew(15deg)',
                        }}
                      >
                        {translatedFields.preview}
                      </div>
                      <span
                        className={classNames(
                          'badge me-2',
                          form.roundedPill ? 'rounded-pill' : false,
                        )}
                        style={{
                          color:
                            form.colorMode === 'DEFAULT'
                              ? '#ffffff'
                              : form.color,
                          backgroundColor:
                            form.backgroundColorMode === 'DEFAULT'
                              ? '#0dcaf0'
                              : form.backgroundColor,
                        }}
                      >
                        {form.name}
                      </span>
                      <span>{source.basic.name}</span>
                    </div>
                  </div>
                )}

              <div>
                <label className="form-label">
                  {translatedFields.badgePage.backgroundColorMode}
                </label>
                <div className="form-control user-select-none">
                  {['DEFAULT', 'CUSTOM'].map((item) => {
                    return (
                      <div key={item} className="form-check form-check-inline">
                        <input
                          id={`yw-badge-backgroundColorMode-${item}`}
                          name="backgroundColorMode"
                          className="form-check-input"
                          type="radio"
                          onChange={onChangeForm}
                          value={item}
                          checked={form.backgroundColorMode === item}
                        />
                        <label
                          className="form-check-label"
                          htmlFor={`yw-badge-backgroundColorMode-${item}`}
                        >
                          {
                            (translatedFields as any).badgePage
                              .BADGE_COLOR_MODE[item]
                          }
                        </label>
                      </div>
                    );
                  })}
                </div>
              </div>

              {form.backgroundColorMode === 'CUSTOM' && (
                <div>
                  <label className="form-label">
                    {translatedFields.badgePage.backgroundColor}
                  </label>
                  <div className="row align-items-center gap-4">
                    <div className="col-4">
                      <div className="vstack gap-4">
                        <div className="row gap-4 align-items-center">
                          <div className="col-2"></div>
                          <div className="col">
                            <select
                              ref={selectBackgroundColorModeRef}
                              name="selectBackgroundColorMode"
                              value={selectBackgroundColorMode}
                              onChange={onChangeForm}
                              className="form-select"
                              aria-label="selectBackgroundColorMode"
                              placeholder={
                                translatedFields.badgePage
                                  .backgroundColorOutputTypePlaceholder
                              }
                            >
                              <option value="HEX">HEX</option>
                              <option value="RGB">RGB</option>
                              <option value="RGBA">RGBA</option>
                              <option value="HSL">HSL</option>
                              <option value="HSLA">HSLA</option>
                            </select>
                          </div>
                        </div>

                        <input
                          type="text"
                          className="form-control"
                          name="backgroundColor"
                          value={form.backgroundColor}
                          onChange={onChangeForm}
                          aria-describedby="backgroundColor"
                          placeholder={
                            translatedFields.badgePage
                              .backgroundColorPlaceholder
                          }
                        />

                        <div className="form-text">
                          {translatedFields.badgePage.sliderBarPlaceholder}
                        </div>
                      </div>
                    </div>
                    <div className="col-7">
                      <IroItem
                        inputColor={form.backgroundColor}
                        selectColorModeRef={selectBackgroundColorModeRef}
                        changeColorCallback={changeBackgroundColorCallback}
                      />
                    </div>
                  </div>
                </div>
              )}

              <div>
                <label className="form-label">
                  {translatedFields.badgePage.ovalStyle}
                </label>
                <select
                  name="roundedPill"
                  value={form.roundedPill + ''}
                  onChange={onChangeForm}
                  className="form-select"
                  aria-label="roundedPill"
                  placeholder={translatedFields.badgePage.ovalStylePlaceholder}
                >
                  <option value="false">{translatedFields.no}</option>
                  <option value="true">{translatedFields.yes}</option>
                </select>
              </div>
            </>
          )}

          <button
            type="submit"
            disabled={
              createPostBadgeMutation.isLoading ||
              updatePostBadgeMutation.isLoading ||
              isDisabledSave
            }
            className="btn btn-success col col-lg-2 my-4"
          >
            {(createPostBadgeMutation.isLoading ||
              updatePostBadgeMutation.isLoading) && <Spinner classs="me-2" />}
            {currentItem ? translatedFields.update : translatedFields.add}
          </button>
        </form>
      </div>
    </Box>
  );
}
